Imports MatrixDataStructures
Public Class FiberTrackingView
    Dim CompositeDisplay As New MainForm
    Dim binarymap As Matrix3DInt16
    Dim threshold As Single = 0.2
    Dim angle As Single = 30

    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        CompositeDisplay.Refresh()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
        AddHandler CompositeDisplay.MouseClickedOnImage, AddressOf ComputeAndDisplayFiber
        AddHandler CompositeDisplay.MouseMovedOnImage, AddressOf donothing

        CompositeDisplay.OpenFile(FormMain.FAVolume, "FA", False, True)
    End Sub

#Region "Form Events"

    Private Sub DTIDirectionMap_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        If Me.CompositeDisplay IsNot Nothing Then CompositeDisplay.Close()
    End Sub
    Private Sub CompositeViewerForm_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus
        CompositeDisplay.Focus()
        CompositeDisplay.BringToFront()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        AddHandler CompositeDisplay.MouseMovedOnImage, AddressOf donothing
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
        AddHandler CompositeDisplay.MouseClickedOnImage, AddressOf ComputeAndDisplayFiber
    End Sub

    Public Function GetFirstBit(ByVal Val As MainForm.DisplayType) As String
        Select Case Val
            Case MainForm.DisplayType.Coronal
                Return "c"
            Case MainForm.DisplayType.Sagittal
                Return "s"
            Case MainForm.DisplayType.Transverse
                Return "t"
            Case Else
                Return "t"
        End Select
    End Function

    Public CurrentActiveDisplay As MainForm.DisplayType = MainForm.DisplayType.Coronal
    Public CurrentActiveSlice As Integer
    Public Sub CurrentSliceInformation(ByVal sender As Object, ByVal e As EventArgs)
        Dim sliceinfo As String = CType(sender, String)
        Select Case Mid(sliceinfo, 1, 1)
            Case "t"
                CurrentActiveDisplay = MainForm.DisplayType.Transverse
            Case "c"
                CurrentActiveDisplay = MainForm.DisplayType.Coronal
            Case "s"
                CurrentActiveDisplay = MainForm.DisplayType.Sagittal
        End Select
        CurrentActiveSlice = CInt(Mid(sliceinfo, 2, sliceinfo.Length - 1))
    End Sub

    Dim WithEvents Composite As MainForm




    Private Sub CompositeViewerForm_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move
        CompositeDisplay.Focus()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Private Sub DTIDirectionMap_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        CompositeDisplay.Focus()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Private Sub CompositeViewerForm_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        ' CompositeDisplay.MdiParent = Me
        CompositeDisplay.Focus()
        CompositeDisplay.BringToFront()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Private Sub CompositeViewerForm_ResizeEnd(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ResizeEnd
        ' CompositeDisplay.MdiParent = Me
        CompositeDisplay.Focus()
        CompositeDisplay.BringToFront()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Private Sub CompositeViewerForm_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
        ' CompositeDisplay.MdiParent = Me
        CompositeDisplay.Focus()
        CompositeDisplay.BringToFront()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

    Private Sub CompositeViewerForm_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Validated
        ' CompositeDisplay.MdiParent = Me
        CompositeDisplay.Focus()
        CompositeDisplay.BringToFront()
        If CompositeDisplay.Visible = False Then CompositeDisplay.Visible = True
        CompositeDisplay.Size = PictureBox4.Size
        Dim temp As Point = Me.PointToScreen(PictureBox4.Location)
        temp.Y += Me.SplitContainer1.Panel1.Height + 5
        CompositeDisplay.Location = temp
        '    AddHandler CompositeDisplay.LostFocus, AddressOf CloseCompositeDisplay
        AddHandler CompositeDisplay.CurrentSlice, AddressOf CurrentSliceInformation
    End Sub

#End Region

    Public Sub donothing(ByVal sender As Object, ByVal e As EventArgs)

    End Sub

    Public Sub ComputeAndDisplayFiber(ByVal sender As Object, ByVal E As EventArgs)
        Dim highlightlocation As Point = CType(sender, Point)
        Dim fiber() As Coordinate
        With FormMain
            If .DiffusionDisplay IsNot Nothing And .FAVolume IsNot Nothing And .IsFACalculated = True Then
                Select Case CompositeDisplay.CurrentActiveDisplay
                    Case MainForm.DisplayType.Transverse
                        Dim startpoints(0) As Coordinate
                        startpoints(0) = New Coordinate(highlightlocation.X, highlightlocation.Y, CompositeDisplay.CurrentSliceIndex)
                        fiber = Fact_3D(startpoints, 0.2)
                        For i As Integer = 0 To fiber.Length - 1
                            CompositeDisplay.HighlightFibers(fiber(i).x, fiber(i).y, 0, True)
                        Next
                    Case MainForm.DisplayType.Coronal
                    Case MainForm.DisplayType.Sagittal
                End Select
            Else
            End If
        End With
    End Sub

    Public Function Fact_3D(ByVal startpoint As Coordinate(), ByVal fathreshold As Single) As Coordinate()
        Dim eigendata As Matrix4DdoubleS = FormMain.DTIClass.ReturnEigenVector(ComputeDTI.Order.Big)
        Dim fadata As Matrix3DSingle = FormMain.DTIClass.ReturnFA
        Dim currentpoint, possiblefinalpoint(3) As Coordinate
        Dim fiber(0) As Coordinate
        '  Dim AngleThreshold As Single
        Dim distance1, distance2, distance3 As Double
        For a As Integer = 0 To startpoint.Length - 1
            MsgBox("a:" & a)
            If startpoint(a).x > 0 And startpoint(a).y > 0 And startpoint(a).z > 0 And _
                startpoint(a).x < fadata.x And startpoint(a).y < fadata.y And startpoint(a).z < fadata.z Then
                currentpoint = startpoint(a)
                fiber(0) = startpoint(a)
                For b As Integer = 1 To 2
                    MsgBox("b:" & b)
                    Dim vectorcurrent As New CoordinateD(((-1) ^ b) * eigendata.data(currentpoint.x, currentpoint.y, currentpoint.z, 0), _
                    ((-1) ^ b) * eigendata.data(currentpoint.x, currentpoint.y, currentpoint.z, 0), _
                    ((-1) ^ b) * eigendata.data(currentpoint.x, currentpoint.y, currentpoint.z, 0))
                    Dim vectorold As New CoordinateD(vectorcurrent.x, vectorcurrent.y, vectorcurrent.z)
                    While fadata(currentpoint.x, currentpoint.y, currentpoint.z) >= fathreshold And _
                              currentpoint.x > 0 And currentpoint.y > 0 And currentpoint.z > 0 And _
                                  currentpoint.x < fadata.x And currentpoint.y < fadata.y And currentpoint.z < fadata.z
                        ' add condition to check angle later
                        vectorcurrent = New CoordinateD(((-1) ^ b) * eigendata.data(currentpoint.x, currentpoint.y, currentpoint.z, 0), _
                    ((-1) ^ b) * eigendata.data(currentpoint.x, currentpoint.y, currentpoint.z, 0), _
                    ((-1) ^ b) * eigendata.data(currentpoint.x, currentpoint.y, currentpoint.z, 0))

                        possiblefinalpoint(0) = New Coordinate(0, 0, 0)
                        possiblefinalpoint(1) = New Coordinate(0, 0, 0)
                        possiblefinalpoint(2) = New Coordinate(0, 0, 0)
                        MsgBox("new point to same fiber")
                        If vectorcurrent.x <> 0 Then
                            possiblefinalpoint(0).x = CShort(currentpoint.x + Math.Sign(vectorcurrent.x))
                            possiblefinalpoint(0).y = CShort(Math.Round((vectorcurrent.y / vectorcurrent.x) * (possiblefinalpoint(0).x - currentpoint.x) + currentpoint.y))
                            possiblefinalpoint(0).z = CShort(Math.Round((vectorcurrent.z / vectorcurrent.x) * (possiblefinalpoint(0).x - currentpoint.x) + currentpoint.z))
                            distance1 = (possiblefinalpoint(0).x - currentpoint.x) ^ 2 + (possiblefinalpoint(0).y - currentpoint.y) ^ 2 + (possiblefinalpoint(0).z - currentpoint.z) ^ 2
                        Else
                            distance1 = 100000000000000000
                        End If

                        If vectorcurrent.y <> 0 Then
                            possiblefinalpoint(1).y = CShort(currentpoint.y + Math.Sign(vectorcurrent.y))
                            possiblefinalpoint(1).x = CShort(Math.Round((vectorcurrent.x / vectorcurrent.y) * (possiblefinalpoint(1).y - currentpoint.y) + currentpoint.x))
                            possiblefinalpoint(1).z = CShort(Math.Round((vectorcurrent.z / vectorcurrent.y) * (possiblefinalpoint(1).y - currentpoint.y) + currentpoint.z))
                            distance2 = (possiblefinalpoint(1).x - currentpoint.x) ^ 2 + (possiblefinalpoint(1).y - currentpoint.y) ^ 2 + (possiblefinalpoint(1).z - currentpoint.z) ^ 2
                        Else
                            distance2 = 100000000000000000
                        End If

                        If vectorcurrent.z <> 0 Then
                            possiblefinalpoint(2).z = CShort(currentpoint.z + Math.Sign(vectorcurrent.z))
                            possiblefinalpoint(2).x = CShort(Math.Round((vectorcurrent.x / vectorcurrent.z) * (possiblefinalpoint(2).z - currentpoint.z) + currentpoint.x))
                            possiblefinalpoint(2).y = CShort(Math.Round((vectorcurrent.y / vectorcurrent.z) * (possiblefinalpoint(2).z - currentpoint.z) + currentpoint.y))
                            distance3 = (possiblefinalpoint(2).x - currentpoint.x) ^ 2 + (possiblefinalpoint(2).y - currentpoint.y) ^ 2 + (possiblefinalpoint(2).z - currentpoint.z) ^ 2
                        Else
                            distance3 = 100000000000000000
                        End If
                        If distance1 = Math.Min(distance1, Math.Min(distance2, distance3)) Then
                            currentpoint = possiblefinalpoint(0)
                        ElseIf distance2 = Math.Min(distance1, Math.Min(distance2, distance3)) Then
                            currentpoint = possiblefinalpoint(1)
                        Else
                            currentpoint = possiblefinalpoint(2)
                        End If
                        ReDim Preserve fiber(fiber.Length)
                        fiber(fiber.Length - 1) = currentpoint
                        vectorold = vectorcurrent
                    End While
                Next
            End If
        Next
        Return fiber
    End Function
End Class

